from abc import ABC, abstractmethod
from typing import Dict
from uuid import uuid4

from core.domain.core_domain_entities.document import Document
from core.domain.entity import AggregateRoot
from core.domain.enums import DocumentClass, PackageStatus


class Package(AggregateRoot, ABC):

    REQUIRED_DOC_CLASSES = []

    def __init__(self, uuid: uuid4, documents: Dict[DocumentClass, Document]):
        self.uuid = uuid
        self.documents = documents
        self.status = PackageStatus.not_defined

    def _doc_classes_does_not_repeat(self):
        doc_classes = [doc_class for doc_class in list(self.documents.keys())]
        for doc_class in doc_classes:
            if doc_classes.count(doc_class) > 1:
                self.assign_status(status=PackageStatus.invalid)

    def _all_needed_doc_classes_are_present(self):
        if not all(
            doc_class in list(self.documents.keys())
            for doc_class in self.REQUIRED_DOC_CLASSES
        ):
            self.assign_status(status=PackageStatus.invalid)

    def validate_package_integrity(self) -> PackageStatus:
        self._doc_classes_does_not_repeat()
        self._all_needed_doc_classes_are_present()
        return self.status

    def assign_status(self, status: PackageStatus):
        self.status = status

    @abstractmethod
    def run_business_logic(self):
        raise NotImplemented
